#include "Channel.h"
#include "Epoll.h"
#include "InetAddress.h"
#include "Socket.h"
#include "EventLoop.h"
#include "Log.h"

#include <cstdio>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstring>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <sys/fcntl.h>
#include <sys/epoll.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>

Channel::Channel(EventLoop* loop, int fd) : m_loop(loop), m_fd(fd)
{
}

Channel::~Channel()
{
}

int Channel::fd()
{
    return m_fd;
}

bool Channel::in_epoll()
{
    bool flag;
    {
        flag=m_in_epoll;
    }
    return flag;
}

uint32_t Channel::events()
{
    return m_events;
}

uint32_t Channel::revents()
{
    return m_revents;
}

void Channel::use_et()
{
    m_events = m_events | EPOLLET;
}

void Channel::enable_reading()
{
    m_events = m_events | EPOLLIN;
    m_loop->update_channel(this);
}

void Channel::disable_reading()
{
    m_events &= ~EPOLLIN;
    m_loop->update_channel(this);
}

void Channel::enable_writing()
{
    m_events = m_events | EPOLLOUT;
    m_loop->update_channel(this);

}

void Channel::disable_writing()
{
    m_events &= ~EPOLLOUT;
    m_loop->update_channel(this);
}

void Channel::disable_all()
{
    m_events=0;
    m_loop->update_channel(this);
}

void Channel::remove()
{
    //todo 问题在这里，这个函数有bug
    disable_all();
    m_loop->remove_channel(this);
}

void Channel::set_inepoll()
{
    m_in_epoll = true;
}

void Channel::set_not_inepoll()
{
    m_in_epoll = false;
}

void Channel::set_revents(uint32_t ev)
{
    m_revents = ev;
}

void Channel::handle_event()
{
    //根据发生的事件类型进行判断
    // 对方已关闭
    if (m_revents & EPOLLRDHUP)
    {   
        //LOG(INFO)<<"EPOLLRDHUP";
         m_close_callback();
    }
    // EPOLLPRI:表示对应的文件描述符有紧急的数据可读;
    else if (m_revents & (EPOLLIN | EPOLLPRI))
    {
        //LOG(INFO)<<"EPOLLIN | EPOLLPRI";
        m_read_callback();
    }
    // 写事件
    //水平触发时，表示缓冲区可写
    //边缘触发时，表示缓冲区由不可写变为可写
    else if (m_revents & EPOLLOUT)
    {
        //LOG(INFO)<<"EPOLLOUT";
        m_write_callback();
    }
    // 其它事件，都视为错误。
    else
    {
        // LOG(INFO)<<"ERROR";
        m_error_callback();
    }
}

void Channel::set_read_callback(std::function<void()> fn)
{
    m_read_callback = fn;
}

void Channel::set_close_callback(std::function<void()> fn)
{
    m_close_callback=fn;
}   
void Channel::set_error_callback(std::function<void()> fn)
{
    m_error_callback=fn;
}

void Channel::set_write_callback(std::function<void()> fn)
{
    m_write_callback=fn;
}